package com.example.wac.service.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.example.wac.constant.Constant;
import com.example.wac.constant.DisconfConstant;
import com.example.wac.enums.ErrorCode;
import com.example.wac.event.MessageEvent;
import com.example.wac.mail.ToEmail;
import com.example.wac.service.MailService;
import com.example.wac.vo.ApiResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @author wuancheng
 * @description
 * @date 2021-08-12 18:03:00
 */

@Slf4j
@Service
public class MailServiceImpl implements MailService {
    @Autowired
    private DefaultMQProducer producer;

    @Autowired
    ApplicationEventPublisher publisher;

    @Autowired
    RedisTemplate redisTemplate;

    @Value("${rocketMq.TOPIC}")
    private String topic;

    @Autowired
    DisconfConstant disconfConstant;

    @Override
    public String rocketSendMail(ToEmail email){
        if (email != null){
            //序列化对象发送消息
            Message message = new Message(topic, "mailTag", JSONObject.toJSONBytes(email));
            log.info("发送mq消息调用邮件发送服务");
            try {
                producer.send(message);
                return "发送邮件成功";
            } catch (Exception e) {
                return "发送邮件失败";
            }
        }else {
            return "发送邮件失败";
        }
    }

    @Override
    public String rocketListenSendMail(ToEmail email) {
        String transactionId = MDC.get(Constant.TRANSACTION_ID);
        String key = "sendEmail:" + email.getTos();
        Boolean absent = redisTemplate.opsForValue().setIfAbsent(key, DateUtil.now(), disconfConstant.getEmailLimitTime(), TimeUnit.SECONDS);
        if (absent){
            publisher.publishEvent(new MessageEvent(email, MDC.get("email"), transactionId));
            return email.toString();
        }else {
            return "一分钟内最多发送相同用户一次邮件["+DateUtil.now()+"]";
        }
    }

    @Override
    public ApiResult rocketListenSendMailCount(ToEmail email) {
        String transactionId = MDC.get(Constant.TRANSACTION_ID);
        String key = "sendEmail:" + email.getTos();
        // 如果key不存在则创建key默认值为0并设置过期时间
        if (!redisTemplate.hasKey(key)) {
            redisTemplate.opsForValue().set(key, 0, disconfConstant.getEmailLimitTime(), TimeUnit.SECONDS);
        }
        // 获取当前的发送次数
        Integer sendCount = (Integer) redisTemplate.opsForValue().get(key);
        if (sendCount < disconfConstant.getEmailSendCount()) {
            publisher.publishEvent(new MessageEvent(email, MDC.get("email"), transactionId));
            //发送成功+1
            redisTemplate.opsForValue().increment(key, 1);
            log.info("MailServiceImpl记录业务Id");
            return ApiResult.success(email);
        } else {
            throw ErrorCode.EMAIL_ERROR.getAppException("一分钟内最多发送相同用户三次邮件");
        }
    }

}
